﻿using Cirrious.MvvmCross.ViewModels;
using System.Windows.Input;
using WebOptimizer.UI.Entities;

namespace WebOptimizer.UI.ViewModels
{
	public partial class TaskCollectionViewModel
	{
		#region Public Members

		#region ActiveSource

		private Source _ActiveSource;
		public Source ActiveSource
		{
			get
			{
				return _ActiveSource;
			}
			set
			{
				_ActiveSource = value;
				RaisePropertyChanged("ActiveSource");
				RaisePropertyChanged("CanEditSource");
			}
		}

		#endregion
		#region ActiveTask

		private Task _ActiveTask;
		public Task ActiveTask
		{
			get
			{
				return _ActiveTask;
			}
			set
			{
				_ActiveTask = value;
				RaisePropertyChanged("ActiveTask");
				RaisePropertyChanged("CanEditTask");
				if (_ActiveTask != null)
				{
					if ((_ActiveTask.Sources != null) && (_ActiveTask.Sources.Count > 0))
						this.ActiveSource = _ActiveTask.Sources[0];
				}
			}
		}

		#endregion
		#region CanEditSource

		public bool CanEditSource
		{
			get
			{
				return this.ActiveSource != null;
			}
		}

		#endregion
		#region CanEditTask

		public bool CanEditTask
		{
			get
			{
				return this.ActiveTask != null;
			}
		}

		#endregion
		#region TaskTypes

		private Sidvall.Data.KeyValueCollection<string, Data.TaskType> _TaskTypes;
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
		public Sidvall.Data.KeyValueCollection<string, Data.TaskType> TaskTypes
		{
			get
			{
				if (_TaskTypes == null)
					this.TaskTypes = Sidvall.Data.KeyValueManager.FromEnum<Data.TaskType>();
				return _TaskTypes;
			}
			set
			{
				_TaskTypes = value;
				RaisePropertyChanged("TaskTypes");
			}
		}

		#endregion

		#region AddSourceCommand

		public ICommand AddSourceCommand
		{
			get
			{
				return new MvxCommand(AddSource);
			}
		}

		#endregion
		#region AddSource

		public void AddSource()
		{
			Source item;

			switch (this.ActiveTask.TaskTypeId)
			{
				case WebOptimizer.Data.TaskType.CompressCss:
					item = new Source()
					{
						IgnoredFiles = ".min.css",
						IncludeSubfolders = true,
						IsEnabled = true,
						SearchPatterns = "*.css",
					};
					break;
				default:
					item = new Source()
					{
						IgnoredFiles = ".intellisense.js|.debug.js|.min.js",
						IncludeSubfolders = true,
						IsEnabled = true,
						SearchPatterns = "*.js",
					};
					break;
			}
			if (!string.IsNullOrWhiteSpace(this.ActiveTask.Path))
				item.Path = System.IO.Path.GetDirectoryName(this.ActiveTask.Path);

			if (this.ActiveTask.Sources == null)
				this.ActiveTask.LoadSources(new SourceCollection());
			this.ActiveTask.Sources.Add(item);
			if (this.ActiveSource == null)
				this.ActiveSource = item;
		}

		#endregion
		#region AddTaskCommand

		public ICommand AddTaskCommand
		{
			get
			{
				return new MvxCommand(AddTask);
			}
		}

		#endregion
		#region AddTask

		public void AddTask()
		{
			Task item;

			item = new Task()
			{
				IsEnabled = true,
				TaskTypeId = Data.TaskType.CompressJavaScript,
			};

			this.ActiveEntity.Add(item);
			if (this.ActiveTask == null)
				this.ActiveTask = item;
		}

		#endregion
		#region ExecuteTaskCommand

		public ICommand ExecuteTaskCommand
		{
			get
			{
				return new MvxCommand(async () => await ExecuteTaskAsync());
			}
		}

		#endregion
		#region ExecuteTaskAsync

		public async System.Threading.Tasks.Task ExecuteTaskAsync()
		{
			WebOptimizer.Workflow.ExecuteTaskJob manager;

			using (var m = new Sidvall.Data.BusyManager(this))
			{
				try
				{
					manager = new Workflow.ExecuteTaskJob();
					manager.Settings = Sidvall.SystemContext.Current.Serializer.Serialize(this.ActiveTask);
					await manager.ExecuteAsync();
				}
				catch (System.Exception ex)
				{
					Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessage("Execution Failed", ex);
				}
			}
		}

		#endregion
		#region ExecuteAllTaskCommand

		public ICommand ExecuteAllTaskCommand
		{
			get
			{
				return new MvxCommand(async () => await ExecuteAllTaskAsync());
			}
		}

		#endregion
		#region ExecuteAllTaskAsync

		public async System.Threading.Tasks.Task ExecuteAllTaskAsync()
		{
			WebOptimizer.Workflow.ExecuteTaskJob manager;

			using (var m = new Sidvall.Data.BusyManager(this))
			{
				try
				{
					manager = new Workflow.ExecuteTaskJob();
					foreach (var item in this.ActiveEntity)
					{
						manager.Settings = Sidvall.SystemContext.Current.Serializer.Serialize(item);
						await manager.ExecuteAsync();
					}
				}
				catch (System.Exception ex)
				{
					Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessage("Execution Failed", ex);
				}
			}
		}

		#endregion
		#region LoadConfigurationCommand

		public ICommand LoadConfigurationCommand
		{
			get
			{
				return new MvxCommand(async () => await LoadConfigurationAsync());
			}
		}

		#endregion
		#region LoadConfigurationAsync

		public async System.Threading.Tasks.Task LoadConfigurationAsync()
		{
			WebOptimizer.Net.Services.V1.TaskCollection tasks;
			string fileContent;

			using (var m = new Sidvall.Data.BusyManager(this))
			{
				try
				{
					var fileNames = Sidvall.UI.SystemContext.Current.DialogManager.OpenFiles(false, null);
					if ((fileNames != null) && (fileNames.Length == 1))
					{
						if (await Sidvall.SystemContext.Current.FileSystemManager.FileExistsAsync(fileNames[0]))
						{
							fileContent = await Sidvall.SystemContext.Current.FileSystemManager.ReadAllTextAsync(fileNames[0]);
							tasks = Sidvall.SystemContext.Current.Serializer.Deserialize<WebOptimizer.Net.Services.V1.TaskCollection>(fileContent);
							this.ActiveEntity = WebOptimizer.UI.SystemContext.Current.EntityFacade.TaskManager.Copy(tasks, Sidvall.Data.CopySettings.FullCopyAll());
						}
					}
				}
				catch (System.Exception ex)
				{
					Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessage("Load Failed", ex);
				}
			}
		}

		#endregion

		#region LoadItemAsync

		protected override async System.Threading.Tasks.Task<TaskCollection> LoadItemAsync()
		{
			TaskCollection items;
			WebOptimizer.Net.Services.V1.TaskCollection data;
			string fileContent;

			if (await Sidvall.SystemContext.Current.FileSystemManager.FileExistsAsync(WebOptimizer.SystemContext.Current.ConfigurationContext.ConfigurationSettings.DataFilePath))
			{
				fileContent = await Sidvall.SystemContext.Current.FileSystemManager.ReadAllTextAsync(WebOptimizer.SystemContext.Current.ConfigurationContext.ConfigurationSettings.DataFilePath);
				data = Sidvall.SystemContext.Current.Serializer.Deserialize<WebOptimizer.Net.Services.V1.TaskCollection>(fileContent);
				items = WebOptimizer.UI.SystemContext.Current.EntityFacade.TaskManager.Copy(data, Sidvall.Data.CopySettings.FullCopyAll());
			}
			else
				items = new TaskCollection();
			WebOptimizer.UI.SystemContext.Current.EntityFacade.TaskManager.AcceptChanges(items);

			return items;
		}

		#endregion
		#region SaveItemAsync

		protected override async System.Threading.Tasks.Task<TaskCollection> SaveItemAsync(TaskCollection item)
		{
			WebOptimizer.Net.Services.V1.TaskCollection tasks;
			string fileContent;

			WebOptimizer.UI.SystemContext.Current.EntityFacade.TaskManager.AcceptChanges(item);
			tasks = WebOptimizer.SystemContext.Current.EntityFacade.TaskManager.Copy(item, Sidvall.Data.CopySettings.FullCopyAll());
			fileContent = Sidvall.SystemContext.Current.Serializer.Serialize(tasks);
			if (await Sidvall.SystemContext.Current.FileSystemManager.FileExistsAsync(WebOptimizer.SystemContext.Current.ConfigurationContext.ConfigurationSettings.DataFilePath))
			{
				await Sidvall.SystemContext.Current.FileSystemManager.WriteAllTextAsync(WebOptimizer.SystemContext.Current.ConfigurationContext.ConfigurationSettings.DataFilePath, fileContent);
			}
			else
			{
				var fileName = Sidvall.UI.SystemContext.Current.DialogManager.SaveFile(null);
				if (!string.IsNullOrWhiteSpace(fileName))
				{
					await Sidvall.SystemContext.Current.FileSystemManager.WriteAllTextAsync(fileName, fileContent);
				}
			}

			return item;
		}

		#endregion

		#region StartAsync

		protected async override System.Threading.Tasks.Task StartAsync()
		{
			await DoLoadAsync();
		}

		#endregion

		#endregion
	}
}
